function save () {
    var message = Ext.get('message');
    var focuson = '';

    Ext.fly('uploadImage').up('td').prev('td').removeClass('invalidText');

    if (!Ext.fly('filename').getValue()) {
        message.update('Please select a photo from your computer.');
        message.addClass('error').highlight();
        Ext.fly('uploadImage').up('td').prev('td').addClass('invalidText');
        return false;
    }
    if (validation('form-gallery') == false) {
        message.update('Please enter required information.');
        message.addClass('error').highlight();
        return false;
    }

    transId = Ext.Ajax.request({
        form: 'form-gallery',
        success: function(response, opts) {
            var obj = Ext.decode(response.responseText);
            if (obj.status == false) {
                if (obj.mesg) {
                    message.update(obj.mesg);
                    message.addClass('error').slideIn().highlight();
                }

                if (Ext.isArray(obj.error)) {
                    Ext.each(obj.error, function(e) {
                        var el  = Ext.get(e.id);
                        var err = '<div class="invalidField" style="display:none;">'+e.code+'</div>';
                        el.addClass('invalid');
                        el.up('td').prev('td').addClass('invalidText');
                        el.insertHtml('afterEnd', err);
                        el.next('div.invalidField').slideIn('t', {
                            duration:.4
                        });
                        if (!focuson) {
                            focuson = e.id;
                            el.focus();
                            el.fadeIn({
                                duration: 2.0
                            });
                        }
                    });
                }
            } else {
                if (obj.mesg) {
                    message.hide().update(obj.mesg);
                    message.addClass('success').slideIn().highlight().pause(5).slideOut('t', { useDisplay:true });
                }
                clearForm();
            }
        },
        failure: function(response, opts) {
            message('server-side failure with status code '+response.status);
        },
        callback: function() {
            Ext.fly('status').slideOut('t', {
                easing: 'easeOut',
                useDisplay: true
            });
            Ext.each(Ext.query('input[type=submit],input[type=reset]', 'form-gallery'), function(e){ e.disabled = false; });
        }
    });

    if (Ext.Ajax.isLoading(transId)) {
        Ext.each(Ext.query('input[type=submit],input[type=reset]', 'form-gallery'), function(e){ e.disabled = true; });
        Ext.fly('status').update('Sending..');
        Ext.fly('status').slideIn('t', {
            easing: 'easeOut'
        });
    }

    return false;
} // save

function message (msg, focus) {
    alert(msg);

    if (typeof focus != 'undefined') {
        Ext.fly(focus).focus();
    }
} // message

function clearForm () {
    Ext.each(Ext.query('input[type=text],input[type=hidden],textarea', 'form-gallery'), function(e){
        e.value = '';
    });
    Ext.fly('preview-photo').dom.src = _webroot+'/img/default.png';
} // clearForm

function cleanError (form) {
    Ext.fly('message').setStyle({ display:'none' }).removeClass('error');
    Ext.select('.invalid', false, form).removeClass('invalid');
    Ext.select('div.invalidField', false, form).remove();
    Ext.select('.invalidText', false, form).removeClass('invalidText');
} // cleanError

function validation (form) {
    var proceed = true;
    var focuson = '';

    cleanError(form);
    Ext.each(Ext.select('.req', false, form).elements, function(e){
        var el = Ext.get(e);

        if (!el.getValue() || el.getValue() == 'select..') {
            proceed = false;
            el.addClass('invalid');
            el.up('td').prev('td').addClass('invalidText');

            if (!focuson) {
                focuson = e.id;
                el.focus();
                el.fadeIn({
                    duration: 2.0
                });
            }
        }
    });

    return proceed;
} // validation

function errorFields (error) {
    var focuson = '';

    Ext.each(error, function(e) {
        var el  = Ext.get(e.id);
        var err = '<div class="invalidField" style="display:none;">'+e.code+'</div>';
            el.addClass('invalid');
            el.prev('td').addClass('invalidText');
            el.insertHtml('afterEnd', err);
            el.next('div.invalidField').slideIn('t', {
                duration:.4
            });
            if (e.clear) {
                el.dom.value = '';
            }
            if (!focuson) {
                focuson = e.id;
                el.focus();
                el.fadeIn({
                    duration: 2.0
                });
            }
    });
} // errorFields

function doUploadImage () {
    var errorMesg = '<h4>Please select an image from your computer.</h4>';
    var mesgBox   = Ext.get('messageBox');

    if (!Ext.fly('uploadImage').getValue()) {
        mesgBox.update(errorMesg);
        Ext.fly('uploadImage').highlight().focus();
        return false;
    } else if (mesgBox.isVisible()) {
        mesgBox.fadeOut({
            easing: 'easeOut',
            useDisplay: true
        });
    }

    Ext.fly('uploadImage').setStyle({  display:'none' });
    Ext.fly('uploadBar').fadeIn();

    AIM.submit(Ext.fly('upload-form').dom, { 'onComplete':completeCallback });
    Ext.fly('upload-form').dom.submit();
    Ext.fly('submit').dom.disabled   = true;
    Ext.fly('uploadImage').dom.value = '';

    Ext.fly('status').update('Uploading..');
        Ext.fly('status').slideIn('t', {
            easing: 'easeOut'
    });
} // doUploadImage

function completeCallback (response) {
    var json = Ext.decode(response);

    Ext.fly('uploadBar').setStyle({  display:'none' });
    Ext.fly('uploadImage').fadeIn();
    Ext.fly('submit').dom.disabled = false;
    Ext.fly('uploadImage').up('td').prev('td').removeClass('invalidText');
    Ext.fly('status').slideOut('t', {
        easing: 'easeOut',
        useDisplay: true
    });

    if (json.status < 0) {
        var err = (json.message) ? json.message : 'Fail upload photo';
        Ext.fly('messageBox').highlight().update(err);
    } else if (json.status == 1) {
        Ext.fly('preview-photo').dom.src = _webroot+'/img/tmp/'+json.thumbnail;
        Ext.fly('filename').dom.value = json.filename;
    }
} // completeCallback